<template>
  <div class="game-container">
    <canvas ref="gameCanvas"></canvas>
    <div v-if="!gameStarted" class="start-screen">
      <h1>Flappy Bird</h1>
      <button @click="startGame">Start Game</button>
    </div>
    <div v-if="gameOver" class="game-over">
      <h2>Game Over!</h2>
      <p>Score: {{ score }}</p>
      <button @click="startGame">Restart</button>
    </div>
    <div class="score-display">Score: {{ score }}</div>
  </div>
</template>

<script>
import planck,{ World, Vec2, Box } from 'planck-js';

export default {
  data() {
    return {
      gameStarted: false,
      gameOver: false,
      score: 0,
      world: null,
      birdBody: null,
      pipes: [],
      ctx: null,
      scale: 30, // 物理引擎米到像素的转换比例
      config: {
        gravity: Vec2(0, -9.8),
        bird: {
          radius: 0.5,
          jumpForce: 5
        },
        pipe: {
          width: 1,
          minGap: 4,    // 新增最小间距
          maxGap: 8,    // 新增最大间距
          spacing: 4,
          spawnX: 20    // 生成起始X坐标
        }
      }
    };
  },
  mounted() {
    this.initCanvas();
    this.setupEventListeners();
  },
  methods: {
    initCanvas() {
      const canvas = this.$refs.gameCanvas;
      canvas.width = 800;
      canvas.height = 600;
      this.ctx = canvas.getContext('2d');
    },
    setupEventListeners() {
      document.addEventListener('keydown', (e) => {
        if (e.code === 'Space') this.jump();
      });
      this.$refs.gameCanvas.addEventListener('click', this.jump);
    },
    startGame() {
      this.pipes=[]
      this.initPhysics();
      this.gameStarted = true;
      this.gameOver = false;
      this.score = 0;
      this.gameLoop();
    },
    initPhysics() {
      this.world = World(this.config.gravity);
      // 添加接触监听器
      this.world.on('begin-contact', (contact) => {
        this.gameOver = true;
      });
      // 创建小鸟
      this.birdBody = this.world.createDynamicBody(Vec2(5, 5));
      this.birdBody.createFixture(Box(0.4, 0.4), {
        density: 1,
        restitution: 0.5,
        userData: 'bird'
      });

      // 创建地面
      const ground = this.world.createBody(Vec2(0, 0));
      ground.createFixture(Box(40, 1), 1);
      ground.setStatic()
    },
    jump() {
      if (!this.gameOver) {
        this.birdBody.setLinearVelocity(Vec2(0, this.config.bird.jumpForce));
      }
    },
    // 修改管道生成方法
    createPipe() {
      const worldHeight = 600 / this.scale;
      const gapHeight = Math.random() * (this.config.pipe.maxGap - this.config.pipe.minGap) + this.config.pipe.minGap;
      const pipeHeight = Math.random() * 8 + 4;

      // 修正碰撞体尺寸（使用半宽半高）
      const pipeHalfWidth = this.config.pipe.width / 2;
      const pipeHalfHeight = pipeHeight / 2;

      // 上管道
      const topPipe = this.world.createKinematicBody(Vec2(
          this.config.pipe.spawnX,
          worldHeight - pipeHalfHeight // 位置对齐顶部
      ));
      topPipe.createFixture(
          Box(pipeHalfWidth, pipeHalfHeight),
          { userData: 'pipe' }
      );

      // 下管道
      const bottomHalfHeight = (worldHeight - pipeHeight - gapHeight) / 2;
      const bottomPipe = this.world.createKinematicBody(Vec2(
          this.config.pipe.spawnX,
          bottomHalfHeight // 位置对齐底部
      ));
      bottomPipe.createFixture(
          Box(pipeHalfWidth, bottomHalfHeight),
          { userData: 'pipe' }
      );

      this.pipes.push({
        top: topPipe,
        bottom: bottomPipe,
        heights: { top: pipeHeight, bottom: worldHeight - pipeHeight - gapHeight },
        scored: false
      });
    },
    updatePipes() {
      // 新增销毁逻辑（加在方法最前面）
      this.pipes = this.pipes.filter(pipe => {
        const pipeX = pipe.top.getPosition().x;
        const shouldKeep = pipeX + this.config.pipe.width > 0; // 允许超出5米缓冲

        if (!shouldKeep) {
          // 从物理世界移除刚体
          this.world.destroyBody(pipe.top);
          this.world.destroyBody(pipe.bottom);
        }
        return shouldKeep;
      });
      // 每得5分增加难度
      if (this.score > 0 && this.score % 5 === 0) {
        this.config.pipe.minGap = Math.max(4, 6 - this.score/5);
        this.config.pipe.maxGap = Math.max(6, 8 - this.score/5);
      }
      const speed=Math.min(this.score/5*0.5+2,5)
      // 管道移动
      this.pipes.forEach(pipe => {
        pipe.top.setLinearVelocity(Vec2(-speed, 0));
        pipe.bottom.setLinearVelocity(Vec2(-speed, 0));
        // 计分检测
        if (!pipe.scored && pipe.top.getPosition().x < this.birdBody.getPosition().x) {
          this.score++;
          pipe.scored = true;
        }
      });

      // 生成新管道
      if (this.pipes.length === 0 || this.pipes[this.pipes.length - 1].top.getPosition().x < this.config.pipe.spawnX - this.config.pipe.width - this.config.pipe.spacing) {
        this.createPipe();
      }
    },
    draw() {
      this.ctx.clearRect(0, 0, 800, 600);

      // 绘制小鸟
      const birdPos = this.birdBody.getPosition();
      this.ctx.save();
      this.ctx.translate(birdPos.x * this.scale, 600 - birdPos.y * this.scale);
      this.ctx.fillStyle = '#FFD700';
      this.ctx.fillRect(-15, -15, 30, 30);
      this.ctx.restore();

      // 绘制管道
      this.pipes.forEach(pipe => {
        this.drawPipe(pipe.top, '#4CAF50');
        this.drawPipe(pipe.bottom, '#4CAF50');
      });
    },
    drawPipe(body, color) {
      const pos = body.getPosition();
       const width = this.config.pipe.width * this.scale;
      const currentPipe = this.pipes.find(p =>
          p.top === body || p.bottom === body
      );
      const physicsHeight = currentPipe.heights[
          body === currentPipe.top ? 'top' : 'bottom'
          ];
      const height = physicsHeight * this.scale;

      this.ctx.fillStyle = color;
      this.ctx.fillRect(
          pos.x * this.scale - width/2,
          600 - pos.y * this.scale - height/2, // Y轴转换
          width,
          height
      );
      // 调试模式显示碰撞框
      if (process.env.NODE_ENV === 'development') {
        this.ctx.strokeStyle = 'red';
        this.ctx.strokeRect(
            pos.x * this.scale - width/2 - 2,
            600 - pos.y * this.scale - height/2 - 2,
            width + 4,
            height + 4
        );
      }
    },
    gameLoop() {
      if (this.gameOver) return;

      this.world.step(1/60);
      this.updatePipes();
      this.draw();

      requestAnimationFrame(this.gameLoop);
    }
  }
};
</script>

<style scoped>
.game-container {
  position: relative;
  width: 800px;
  height: 600px;
  margin: 0 auto;
}

canvas {
  border: 1px solid #333;
  background: #87CEEB;
}

.start-screen, .game-over {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  background: rgba(255, 255, 255, 0.9);
  padding: 20px;
  border-radius: 10px;
}

button {
  padding: 10px 20px;
  font-size: 1.2em;
  cursor: pointer;
  background: #4CAF50;
  border: none;
  color: white;
  border-radius: 5px;
}

.score-display {
  position: absolute;
  top: 20px;
  left: 20px;
  font-size: 24px;
  color: white;
  text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
</style>
